package com.hhd.pdf.components.extField;

import com.hhd.pdf.CommonUtils;
import com.hhd.pdf.components.AbstractPdfComponent;
import com.hhd.pdf.context.GeneratorContext;
import com.hhd.pdf.utils.PdfUtils;
import com.hhd.pdf.variable.ParsedFormula;
import com.hhd.pdf.variable.VariableContext;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfDiv;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

@Component
public class ExtFieldComponent extends AbstractPdfComponent {
    @Autowired
    ExtFieldAdapter extFieldAdapter;

    @Override
    public void parseComponent(Element element, GeneratorContext context) throws Exception {
        VariableContext rootVariableContext = context.createRootVariableContext();
        String dataId = getFormulaStringValue(getDataIdFormula(element), rootVariableContext);
        context.getDocument().addAll(createExtFields(dataId, context, element));
    }

    private Collection<? extends com.itextpdf.text.Element> createExtFields(String dataId,
                                                                            GeneratorContext context,
                                                                            Element element) {
        if (CommonUtils.isEmpty(dataId)) return CommonUtils.newList();
        List<VariableContext> variableContexts = context.createRootVariableContext().subContextByFormula(ParsedFormula.formula(dataId));
        if (CommonUtils.isEmpty(variableContexts)) return CommonUtils.newList();
        List<ExtFieldVo> extFields = extFieldAdapter.getExtFields(dataId, context.getGeneratorParameters().getFormType(), variableContexts.get(0));
        int colNum = getColNum(element);
        PdfPTable table = getTable(context, colNum, element);

        int count = 0;
        for (ExtFieldVo extField : extFields) {
            table.addCell(createCell(extField, context));
            count++;
        }

        while (count % colNum != 0) {
            table.addCell(PdfUtils.createCell());
            count++;
        }

        return getPdfDivs(context, table);
    }

    private List<PdfDiv> getPdfDivs(GeneratorContext context, PdfPTable table) {
        PdfDiv pdfDiv = PdfUtils.wrapDiv(table, 0, 30, 0, 30);
        context.getDocument().add(pdfDiv);
        return CommonUtils.newList(pdfDiv);
    }

    private PdfPCell createCell(ExtFieldVo extField, GeneratorContext context) {
        PdfPCell res = createCellElement();
        res.addElement(createParagraph(extField, context));
        res.setMinimumHeight(30);
        return res;
    }

    private com.itextpdf.text.Element createParagraph(ExtFieldVo extField,
                                                      GeneratorContext context) {
        return PdfUtils.createParagraph(extField.getString(),
                context.getGeneratorParameters().getFont(),
                Paragraph.ALIGN_LEFT);
    }

    private PdfPCell createCellElement() {
        PdfPCell cell = PdfUtils.createCell();
        cell.setVerticalAlignment(com.itextpdf.text.Element.ALIGN_TOP);
        return cell;
    }

    private PdfPTable getTable(GeneratorContext context, int colNum, Element element) {
        PdfPTable table = PdfUtils.createTable(colNum, context.getGeneratorParameters().getInitPageWidth());
        resolveWidth(table, element, colNum);
        return table;
    }

    private static void resolveWidth(PdfPTable table, Element element, int colNum) {
        try {
            List<Element> elements = element.elements();
            int[] res = new int[colNum];

            for (int i = 0; i < colNum; i++) {
                Element element1 = elements.get(i);
                Attribute width = element1.attribute("width");
                res[i] = Integer.parseInt(width.getValue());
            }
            table.setWidths(res);
        } catch (Exception e) {
        }
    }

    private int getColNum(Element element) {
        try {
            Attribute colNum = element.attribute("colNum");
            return Integer.parseInt(colNum.getText());
        } catch (Exception e) {
            return 2;
        }
    }

    private String getFormType(Element element) {
        try {
            Attribute attribute = element.attribute("formType");
            if (CommonUtils.isEmpty(attribute)) {
                attribute = element.attribute("form-type");
                return attribute.getText();
            } else {
                return attribute.getText();
            }
        } catch (Exception e) {
            return "";
        }
    }

    private String getDataIdFormula(Element element) {
        try {
            Attribute attribute = element.attribute("data-id");
            String dataId = null;
            if (CommonUtils.isEmpty(attribute)) {
                attribute = element.attribute("dataId");
                dataId = attribute.getText();
            } else {
                dataId = attribute.getText();
            }
            return dataId;
        } catch (Exception e) {
            return "";
        }
    }

    @Override
    public String getName() {
        return "ext-field";
    }
}
